home *** CD-ROM | disk | FTP | other *** search
- /* ---------------------------------------------------------------------- */
- /* Copyright (C) 1991 by Natürlich! */
- /* This file is copyrighted! */
- /* Refer to the documentation for details. */
- /* ---------------------------------------------------------------------- */
- #include <stdio.h>
- #include "defines.h"
- #include "nasm.h"
- #include "debug.h"
- #include "labels.h"
- #include "exprfast.h"
-
- extern label huge *h_local[SEP], huge *t_local[SEP], huge *l_local,
- huge *h_global[SEP], huge *t_global[SEP], huge *l_global,
- huge *h_macro[SEP], huge *t_macro[SEP], huge *l_macro;
- extern int u_local, u_global, u_macro;
- extern char is_where[], err_defined[];
- extern int _in_macro, runnable, _in_instr;
- extern lword l_hash;
-
-
- label *find_label( s)
- register char *s;
- {
- register label huge *p;
- register lword hash;
- register int res;
-
- ENTER("find_label");
-
- l_hash = hash = calc_hash( s + 1);
- p = h_macro[ u_macro = is_where[*s]];
- while( p && (p->hash < hash ||
- (p->hash == hash && (res = strcmp( p->name, s)) < 0)))
- p = p->next;
- l_macro = p;
-
- if( ! found( p, hash) || res) /* if not found or at end of table */
- {
- if( *s == '?' || *s == ':')
- {
- l_hash = hash = calc_hash( s + 2);
- p = h_local[ u_local = is_where[ s[1]]];
- while( p && (p->hash < hash ||
- (p->hash == hash && (res = strcmp( p->name, s)) < 0)))
- p = p->next;
- l_local = p;
- }
- else
- {
- p = h_global[ u_global = is_where[*s]];
- while( p && (p->hash < hash ||
- (p->hash == hash && (res = strcmp( p->name, s)) < 0)))
- p = p->next;
- l_global = p;
- }
- if( ! found(p, hash) || res)
- {
- LEAVE();
- return( 0);
- }
- }
- LEAVE();
- return( p);
- }
-
-
- void undefine( s)
- char *s;
- {
- register label huge *p;
- int is_local = (*s == '?' || *s == ':');
-
- u_local = u_global = -1; /* if we find a macro label this remains -1 */
- if( p = find_label( s))
- if( ! p->refs)
- if( u_local < 0 && u_global < 0)
- {
- auslinker( h_macro, t_macro, l_macro, u_macro, p);
- }
- else
- if( is_local)
- {
- auslinker( h_local, t_local, l_local, u_local, p);
- }
- else
- {
- auslinker( h_global, t_global, l_global, u_global, p);
- }
- else
- nerror("Label has pending forward references");
- else
- nwarning("Label is unknown to me");
- }
- /* ---------------------------------------------------------- */
- /* This routine is called when a forward label */
- /* is encountered: */
- /* -- Note that the tables have already been searched -- */
- /* e.g.: */
- /* sta foo */
- /* not: foo lda foo */
- /* not: foo: = 56 */
- /* not: foo *=$600 */
- /* ---------------------------------------------------------- */
- label *enter_flabel( s, ex)
- char *s;
- register expr huge *ex;
- {
- register label *p;
- int is_local = (*s == '?' || *s == ':');
-
- ENTER("enter forward label");
- #if DEBUG
- fprintf( ESTREAM, "with %s as name, and some s_expr @$%lX\n", s, ex);
- #endif
- if( is_local)
- p = llab_alloc();
- else
- p = lab_alloc();
- p->refs = 0;
- p->name = s;
- p->hash = l_hash;
- if( runnable)
- p->type = L_NORMAL | L_REF;
- else
- p->type = L_PC | L_NORMAL | L_REF;
- refer( p, ex);
-
- if( is_local)
- {
- MESS("linking into local");
- einlinker( h_local, t_local, l_local, u_local, p);
- }
- else
- if( _in_macro)
- {
- MESS("linking into macro");
- einlinker( h_macro, t_macro, l_macro, u_macro, p);
- }
- else
- {
- MESS("linking into global");
- einlinker( h_global, t_global, l_global, u_global, p);
- }
- LEAVE();
- return( p);
- }
-
- void page0decl( s)
- register char *s;
- {
- register label huge *p;
- register expr huge *ex;
- int is_local = (*s == '?' || *s == ':');
-
- ENTER("page0decl");
- if( runnable)
- {
- nwarning(".ZEXT probably not meaningful with -r option");
- nmessage("But we're gonna do it anyway!");
- }
- if( ! find_label( s)) /* if not found or at end of table */
- if( ! is_local)
- {
- p = lab_alloc();
- p->refs = 0;
- p->name = s;
- p->hash = l_hash;
- p->type = L_ZERO | L_LINKZERO;
- ex = exp_alloc();
- ex->fix = FIX_NOTHING;
- refer( p, ex);
- einlinker( h_global, t_global, l_global, u_global, p);
- }
- else
- nserror("Can't use local labels here", s);
- else
- nserror( err_defined, s);
- LEAVE();
- }
-
- /* ---------------------------------------------------------- */
- /* The variety of label dumping routines, really BEG for a */
- /* a one-that-does-it-all-routine */
- /* ---------------------------------------------------------- */
- void dump_open()
- {
- register int i, j, k;
- int f = 0;
- register label huge *p;
-
- ENTER("dump_open");
- for( k = 0; k != 2; k++)
- for( i = 0; i != SEP; i++)
- if( p = k ? h_macro[ i] : h_global[ i])
- do
- if( dumpable( p))
- {
- if( ! f)
- {
- f = 1;
- j = 0;
- printf("Linkable symbols:\n");
- }
- if( ++j == 7)
- {
- j = 0;
- putchar( '\n');
- }
- printf( "%c%-8.8s ",
- (char) (p->type & L_ZERO
- ? (p->refs ? ',' : '#')
- : (p->refs ? ' ' : '*')),
- p->name);
- }
- while( p = p->next);
- puts( "\n");
- LEAVE();
- }
-
- /* ---------------------------------------------------------- */
- /* Remove all labels starting with @ from macro table */
- /* ---------------------------------------------------------- */
- void clean_mats()
- {
- register label huge *p;
-
- ENTER("dump_open");
- for( p = h_macro[ 1]; p; p = p->next)
- if( p->refs)
- nerror("'@' macro label still has open refs", p->name);
- h_macro[ 1] = 0;
- LEAVE();
- }
-
-